#include <iostream>
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>

void setNonBlock(int fd) 
{
    int fl = fcntl(fd, F_GETFL); //获取文件描述符打开时的标记位，O_CREAT|O_WRONLY|O_TRUNC
    if(fl < 0)
    {
        std::cerr << "fcntl error" << std::endl;
        exit(0);
    }
    fcntl(fd, F_SETFL, fl | O_NONBLOCK); //加上非阻塞，O_CREAT|O_WRONLY|O_TRUNC|O_NONBLOCK
}

int main() 
{
    setNonBlock(0);
    while(true)
    {
        char buffer[1024];
        ssize_t s = read(0, buffer, sizeof(buffer)-1);
        if(s > 0) 
        {
            buffer[s] = '\0';
            std::cout << "echo# " << buffer << std::endl;
            sleep(1);
        }
        else if(s == 0) 
        {
            std::cout << "end stdin" << std::endl; //读到了文件结尾（键入Ctrl+D）
            break;
        }
        else
        {
            // 非阻塞等待，若数据未就绪，会按照出错返回，且均返回-1，区分具体情况用errno
            if(errno == EWOULDBLOCK) //EWOULDBLOCK 或 EAGAIN，数据取尽，无数据就绪
            {
                std::cout << "数据未就绪, errno: " << errno << std::endl;

                // 等待中，可以做其他工作
                // ...

                sleep(1);
            }
            else if(errno == EINTR) //EINTR，上次读取被信号中断
            {
                std::cout << "io interrupted by signal, try again..." << std::endl;
                sleep(1);
            }
            else //发生错误
            {
                std::cout << "read nothing or read error..." << std::endl;
                break;
            }
        }
    }
    return 0;
}